using System;
using Microsoft.WowAddonStudio.FrameXml.Components.Support;
using Microsoft.WowAddonStudio.FrameXml.Serialization;
using Microsoft.WowAddonStudio.FrameXml.Serialization.LayoutFrames;
using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Components.Tests.Support
{
	[TestFixture]
	public class ScriptInjectorTest
	{
		#region SetUp

		[SetUp]
		public void SetUp()
		{
		}

		#endregion

		#region TearDown

		[TearDown]
		public void TearDown()
		{
		}

		#endregion

		#region Tests

		[Test(Description = "")]
		public void Test_ScriptInjectorAdditionAndRemove()
		{
			var control = new FrameControl(new Frame {Movable = true, Name = "TestFrame"});

			//Inject "Movable" script
            ScriptInjector.InjectScript(control, ScriptType.Movable);

			Assert.IsNotNull(control.ScriptContainer);

			Assert.AreEqual(3, control.ScriptContainer.Count);

			foreach (Script script in control.ScriptContainer.Scripts)
			{
				Console.WriteLine(String.Format("{0} => {1}",  script.EventName, script.ScriptBlock));
				Assert.IsNotNull(script);
				switch (script.EventName)
				{
					case EventName.OnLoad:
						Assert.IsTrue(script.ScriptBlock.Contains("self:RegisterForDrag(\"LeftButton\")"));
						break;
					case EventName.OnDragStart:
						Assert.AreEqual("self:StartMoving();", script.ScriptBlock);
						break;
					case EventName.OnDragStop:
						Assert.AreEqual("self:StopMovingOrSizing();", script.ScriptBlock);
						break;
					default:
						Assert.Fail(string.Format("Invalid EventName: {0}", script.EventName ));
						break;
				}
			}
			//Set Movable false
			//((Frame) control.LayoutFrame).Movable = false;
			// ScriptInjector.InjectScript(ScriptType.Movable, control);

			Assert.AreEqual(3, control.ScriptContainer.Count);
		}


		[Test(Description = "")]
		public void Test_ScriptInjectorAdditionAndRemoveWithExistingScripts()
		{
			//Add dummy scripts
		    var control = new FrameControl(new Frame {Movable = true, Name = "TestFrame"});

            control.ScriptContainer.Add(EventName.OnLoad, "TestFunctionCall();");
            control.ScriptContainer.Add(EventName.OnSizeChanged, "TestSizeChanged();");

			Assert.AreEqual(2, control.ScriptContainer.Count);

			//Inject "Movable" script
            ScriptInjector.InjectScript(control, ScriptType.Movable);

			Assert.IsNotNull(control.ScriptContainer);

			Assert.AreEqual(4, control.ScriptContainer.Count);

			foreach (Script script in control.ScriptContainer.Scripts)
			{
				Console.WriteLine(String.Format("{0} => {1}", script.EventName, script.ScriptBlock));
				Assert.IsNotNull(script);
				switch (script.EventName)
				{
					case EventName.OnLoad:
						Assert.IsTrue(script.ScriptBlock.Contains("self:RegisterForDrag(\"LeftButton\")"));
						Assert.IsTrue(script.ScriptBlock.Contains("TestFunctionCall();"));
						break;
					case EventName.OnDragStart:
						Assert.AreEqual("self:StartMoving();", script.ScriptBlock);
						break;
					case EventName.OnDragStop:
						Assert.AreEqual("self:StopMovingOrSizing();", script.ScriptBlock);
						break;
					default:
						if (script.EventName == EventName.OnSizeChanged)
						{
							Assert.AreEqual("TestSizeChanged();", script.ScriptBlock);
						}
						else
						{
							Assert.Fail(string.Format("Invalid EventName: {0}", script.EventName));							
						}
						break;
				}
			}
			//Set Movable false
			//((Frame)control.LayoutFrame).Movable = false;
            ScriptInjector.InjectScript(control, ScriptType.Movable);

			Assert.AreEqual(2, control.ScriptContainer.Count);

			Assert.AreEqual("TestFunctionCall();", control.ScriptContainer[EventName.OnLoad].ScriptBlock);
			Assert.AreEqual("TestSizeChanged();", control.ScriptContainer[EventName.OnSizeChanged].ScriptBlock);
		}

		[Test(Description = "")]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Test_InitFailed()
		{
            ScriptInjector.InjectScript(null, ScriptType.Movable);
		}

		[Test(Description = "")]
		public void Test_ScriptInjectorResizableAdditionAndRemove()
		{
			var control = new FrameControl(new Frame { Movable = true, Name = "TestFrame" });

			//Inject "Movable" script
            ScriptInjector.InjectScript(control, ScriptType.Resizable);

			Assert.IsNotNull(control.ScriptContainer);

			Assert.AreEqual(0, control.ScriptContainer.Count);

			//Check ScriptContainer if Resizable is implemented
		}

		#endregion
	}
}